/* this is the scanner example from the JLex website 
   (with small modifications to make it more readable) */

%%

%{
  private int cuenta_comentario = 0;
%} 

%line
%char
%state COMMENT
%full

%debug


NO_NUEVA_LINEA_ESPACIO_BLANCO_CHAR=[\ \t\b\012]
NUEVA_LINEA=\r|\n|\r\n
ESPACIO_BLANCO_CHAR=[\n\r\ \t\b\012]
STRING_TEXTO=(\\\"|[^\n\r\"]|\\{ESPACIO_BLANCO_CHAR}+\\)*
COMENTARIO_TEXTO=([^*/\n]|[^*\n]"/"[^*\n]|[^/\n]"*"[^/\n]|"*"[^/\n]|"/"[^*\n])*


LETRA=[A-Za-z]
NUM=[0-9]
NUM_ENT= {NUM}+
NUM_REAL={NUM}+.{NUM}+
ID= {LETRA}({LETRA}|{NUM})*
VECTOR= \[{NUM}*\]


%% 

<YYINITIAL> {
  "," 		|
  ":" 		|
  ";" 		|
  "(" 		|
  ")" 		|
  "{" 		|
  "}" 		|
  "+"	 	|
  "-"	 	|
  "/" 		|
  "*"		|
  "%"	 	|
  "!"		|
  "=" 		{ return (new Yytoken(yycharat(0),yytext(),yyline,yychar,yychar+1)); }
  "(!=|==)" 	{ return (new Yytoken(Token.COMP_IGUALDAD,yytext(),yyline,yychar,yychar+2)); }
  "(<|<=|>|>=)" { return (new Yytoken(Token.COMP_DESIG,yytext(),yyline,yychar,yychar+1)); }
  "->" 		{ return (new Yytoken(Token.INICIO_PS,yytext(),yyline,yychar,yychar+2)); }
  "if"  	{ return (new Yytoken(Token.IF,yytext(),yyline,yychar,yychar+1)); }
  "then"  	{ return (new Yytoken(Token.THEN,yytext(),yyline,yychar,yychar+1)); }
  "elseif"  	{ return (new Yytoken(Token.ELSEIF,yytext(),yyline,yychar,yychar+1)); }
  "else"  	{ return (new Yytoken(Token.ELSE,yytext(),yyline,yychar,yychar+1)); }
  "while"  	{ return (new Yytoken(Token.WHILE,yytext(),yyline,yychar,yychar+1)); }
  "loop"  	{ return (new Yytoken(Token.LOOP,yytext(),yyline,yychar,yychar+1)); }
  "ifquit"  	{ return (new Yytoken(Token.IFQUIT,yytext(),yyline,yychar,yychar+1)); }
  "ifnever"  	{ return (new Yytoken(Token.IFNEVER,yytext(),yyline,yychar,yychar+1)); }
  "quit"  	{ return (new Yytoken(Token.QUIT,yytext(),yyline,yychar,yychar+1)); }
  "function"  	{ return (new Yytoken(Token.FUNCTION,yytext(),yyline,yychar,yychar+1)); }
  "true"  	{ return (new Yytoken(Token.TRUE,yytext(),yyline,yychar,yychar+1)); }
  "false"  	{ return (new Yytoken(Token.FALSE,yytext(),yyline,yychar,yychar+1)); }
  "(boolean | int |real | string)"  	{ return (new Yytoken(Token.TIPO,yytext(),yyline,yychar,yychar+1)); }
  "(and|or)"  	{ return (new Yytoken(Token.OP_LOGICO,yytext(),yyline,yychar,yychar+1)); }

  {NO_NUEVA_LINEA_ESPACIO_BLANCO_CHAR}+ { }

  "/*" { yybegin(COMMENT); cuenta_comentario++; }

  \"{STRING_TEXTO}\" {
    String str =  yytext().substring(1,yylength()-1);
    return (new Yytoken(40,str,yyline,yychar,yychar+yylength()));
  }
  
  \"{STRING_TEXTO} {
    String str =  yytext().substring(1,yytext().length());
    Utility.error(Utility.E_UNCLOSEDSTR);
    return (new Yytoken(41,str,yyline,yychar,yychar + str.length()));
  } 
  

  {NUM_ENT} { return (new Yytoken(Token.NUM_ENT,yytext(),yyline,yychar,yychar+yylength())); }  
  {NUM_REAL} { return (new Yytoken(Token.NUM_REAL,yytext(),yyline,yychar,yychar+yylength())); }  
  {VECTOR} 	{ return (new Yytoken(Token.VECTOR,yytext(),yyline,yychar,yychar+1)); }	

  {ID} { return (new Yytoken(43,yytext(),yyline,yychar,yychar+yylength())); }  
}

<COMMENT> {
  "/*" { cuenta_comentario++; }
  "*/" { if (--cuenta_comentario == 0) yybegin(YYINITIAL); }
  {COMENTARIO_TEXTO} { }
}


{NUEVA_LINEA} { }

. {
  System.out.println("Illegal character: <" + yytext() + ">");
	Utility.error(Utility.E_UNMATCHED);
}
